﻿using System;
using System.Collections.Generic;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Linq;
using System.IO.IsolatedStorage;
using System.Windows.Data;
using System.Collections.ObjectModel;
using GalaSoft.MvvmLight.Messaging;
using System.Text.RegularExpressions;

namespace mvvmCommon
{
    //Cover money to chars
    public class ReadMoney
    {
        public static string str = " ";

        public static string ToString(decimal number)
        {
            string s = number.ToString("#");
            string[] so = new string[] { "không", "một", "hai", "ba", "bốn", "năm", "sáu", "bảy", "tám", "chín" };
            string[] hang = new string[] { "", "ngàn", "triệu", "tỷ" };
            int i, j, donvi, chuc, tram;

            bool booAm = false;
            decimal decS = 0;
            //Tung addnew
            try
            {
                decS = Convert.ToDecimal(s.ToString());
            }
            catch
            {
            }
            if (decS < 0)
            {
                decS = -decS;
                s = decS.ToString();
                booAm = true;
            }
            i = s.Length;
            if (i == 0)
                str = so[0] + str;
            else
            {
                j = 0;
                while (i > 0)
                {
                    donvi = Convert.ToInt32(s.Substring(i - 1, 1));
                    i--;
                    if (i > 0)
                        chuc = Convert.ToInt32(s.Substring(i - 1, 1));
                    else
                        chuc = -1;
                    i--;
                    if (i > 0)
                        tram = Convert.ToInt32(s.Substring(i - 1, 1));
                    else
                        tram = -1;
                    i--;
                    if ((donvi > 0) || (chuc > 0) || (tram > 0) || (j == 3))
                        str = hang[j] + str;
                    j++;
                    if (j > 3) j = 1;
                    if ((donvi == 1) && (chuc > 1))
                        str = "một " + str;
                    else
                    {
                        if ((donvi == 5) && (chuc > 0))
                            str = "lăm " + str;
                        else if (donvi > 0)
                            str = so[donvi] + " " + str;
                    }
                    if (chuc < 0)
                        break;
                    else
                    {
                        if ((chuc == 0) && (donvi > 0)) str = "lẻ " + str;
                        if (chuc == 1) str = "mười " + str;
                        if (chuc > 1) str = so[chuc] + " mươi " + str;
                    }
                    if (tram < 0) break;
                    else
                    {
                        if ((tram > 0) || (chuc > 0) || (donvi > 0)) str = so[tram] + " trăm " + str;
                    }
                    str = " " + str;
                }
            }
            if (booAm) str = "Âm " + str;
            return str;// = str+ "đồng chẵn";

        }

        private static string[] ChuSo = new string[10] { " không", " một", " hai", " ba", " bốn", " năm", " sáu", " bẩy", " tám", " chín" };
        private static string[] Tien = new string[6] { "", " ngàn", " triệu", " tỷ", " nghìn tỷ", " triệu tỷ" };
        // Hàm đọc số thành chữ
        public static string ReadMoneyByChar(decimal SoTien, string strTail)
        {
            int lan, i;
            decimal so;
            string KetQua = "", tmp = "";
            int[] ViTri = new int[6];
            if (SoTien < 0) return "Số tiền âm !";
            if (SoTien == 0) return "Không đồng !";
            if (SoTien > 0)
            {
                so = SoTien;
            }
            else
            {
                so = -SoTien;
            }
            //Kiểm tra số quá lớn
            if (SoTien > 8999999999999999)
            {
                SoTien = 0;
                return "";
            }
            ViTri[5] = (int)(so / 1000000000000000);
            so = so - long.Parse(ViTri[5].ToString()) * 1000000000000000;
            ViTri[4] = (int)(so / 1000000000000);
            so = so - long.Parse(ViTri[4].ToString()) * +1000000000000;
            ViTri[3] = (int)(so / 1000000000);
            so = so - long.Parse(ViTri[3].ToString()) * 1000000000;
            ViTri[2] = (int)(so / 1000000);
            ViTri[1] = (int)((so % 1000000) / 1000);
            ViTri[0] = (int)(so % 1000);
            if (ViTri[5] > 0)
            {
                lan = 5;
            }
            else if (ViTri[4] > 0)
            {
                lan = 4;
            }
            else if (ViTri[3] > 0)
            {
                lan = 3;
            }
            else if (ViTri[2] > 0)
            {
                lan = 2;
            }
            else if (ViTri[1] > 0)
            {
                lan = 1;
            }
            else
            {
                lan = 0;
            }
            for (i = lan; i >= 0; i--)
            {
                tmp = DocSo3ChuSo(ViTri[i]);
                KetQua += tmp;
                if (ViTri[i] != 0) KetQua += Tien[i];
                if ((i > 0) && (!string.IsNullOrEmpty(tmp))) KetQua += ",";//&& (!string.IsNullOrEmpty(tmp))
            }
            if (KetQua.Substring(KetQua.Length - 1, 1) == ",") KetQua = KetQua.Substring(0, KetQua.Length - 1);

            //Doc so le neu co
            string sole = "";
            if (SoTien.ToString().Contains(","))
            {
                string[] s = SoTien.ToString().Split(',');
                int phanle = int.Parse(s[1]);
                if (phanle != 0)
                    sole = " lẻ" + DocSo3ChuSo(phanle);
            }
            KetQua = KetQua.Trim() + sole + " " + ReadUnit(strTail);
            return KetQua.Substring(0, 1).ToUpper() + KetQua.Substring(1);
        }
        // Hàm đọc số có 3 chữ số
        private static string DocSo3ChuSo(int baso)
        {
            int tram, chuc, donvi;
            string KetQua = "";
            tram = (int)(baso / 100);
            chuc = (int)((baso % 100) / 10);
            donvi = baso % 10;
            if ((tram == 0) && (chuc == 0) && (donvi == 0)) return "";
            if (tram != 0)
            {
                KetQua += ChuSo[tram] + " trăm";
                if ((chuc == 0) && (donvi != 0)) KetQua += " linh";
            }
            if ((chuc != 0) && (chuc != 1))
            {
                KetQua += ChuSo[chuc] + " mươi";
                if ((chuc == 0) && (donvi != 0)) KetQua = KetQua + " linh";
            }
            if (chuc == 1) KetQua += " mười";
            switch (donvi)
            {
                case 1:
                    if ((chuc != 0) && (chuc != 1))
                    {
                        KetQua += " mốt";
                    }
                    else
                    {
                        KetQua += ChuSo[donvi];
                    }
                    break;
                case 5:
                    if (chuc == 0)
                    {
                        KetQua += ChuSo[donvi];
                    }
                    else
                    {
                        KetQua += " lăm";
                    }
                    break;
                default:
                    if (donvi != 0)
                    {
                        KetQua += ChuSo[donvi];
                    }
                    break;
            }
            return KetQua;
        }

        private static string ReadUnit(string currency)
        {
            Dictionary<string, string> allCurrency = new Dictionary<string, string>();
            allCurrency.Add("VND", "đồng");
            allCurrency.Add("USD", "đô la Mỹ");
            allCurrency.Add("EUR", "euro");
            allCurrency.Add("AUD", "đô la Úc");
            allCurrency.Add("JPY", "yên Nhật");
            allCurrency.Add("XAU", "chỉ /phân");
            allCurrency.Add("HKD", "đô Hongkong");
            allCurrency.Add("THB", "bạt Thái");

            return allCurrency[currency];
        }
    }

    //Copier
    public static class Copier
    {
        public static T Clone<T>(T data)
        {
            T result = (T)typeof(T).GetConstructor(new Type[] { }).Invoke(new object[] { });

            Copier.Copy<T>(result, data);

            return result;
        }

        public static bool Copy<T>(T result, T data)
        {
            if (result == null || data == null) return false;
            var list = result.GetType().GetProperties();
            foreach (var prop in list)
                prop.SetValue(result, prop.GetValue(data, null), null);
            return true;
        }
    }

    public static class MyHelper
    {

        public static BusyIndicator AppProcessing;

        public static void IsBusy()
        {
            MyHelper.AppProcessing.IsBusy = true;
        }

        public static void IsFree()
        {
            MyHelper.AppProcessing.IsBusy = false;
        }

        public static string CoverBackMoney(string price)
        {            
            if (IsolatedStorageSettings.ApplicationSettings["currentCulture"].ToString().Equals("vi-VN"))
            {
                price = price.Replace(",", "");
                return price.Replace(".", ",");
            }
            return price.Replace(",", "");
        }
        public static string Format_Price(string Price)
        {
            if (Price == null) return "0";
            string pre = "";
            if (Price.Contains("-"))
            {
                pre = "-";
                Price = Price.Replace("-", "");
            }
            string balance = "";
            string[] lstSplit = { Price };
            if (Price.Contains(","))
                lstSplit = Price.Split(',');
            else if (Price.Contains("."))
                lstSplit = Price.Split('.');

            Price = lstSplit[0];
            if (lstSplit.Count() > 1)
            {
                balance = lstSplit[1];
                balance = RemoveEndZero(balance);
            }

            if (Price == "0" && balance.Equals("0"))
            {
                return "0";
            }

            string tmp = "";
            while (Price.Length > 3)
            {
                tmp = "," + Price.Substring(Price.Length - 3) + tmp;
                Price = Price.Substring(0, Price.Length - 3);
            }
            tmp = Price + tmp + (balance.Equals("0") || balance.Equals("") ? "" : "." + balance);
            return pre + tmp;
            //if (Price.Equals(""))
            //    return "0";
            //else
            //    return String.Format("{0:#,0.###}", decimal.Parse(Price));
        }

        private static string RemoveEndZero(string str)
        {
            int count = str.Length - 1;
            for (int i = count; i > 0; i--)
                if (str[i].ToString().Equals("0"))
                {
                    if (i == 0)
                        return "";
                    str = str.Remove(i);
                }
                else
                    return str;
            return str;

        }

        //List Message
        public static Dictionary<string, string> ListMessage = new Dictionary<string, string>() 
        {
            {"True","True"},
            {"False","False"},                  
        };       

        public static T Clone<T>(T data)
        {
            T result = (T)typeof(T).GetConstructor(new Type[] { }).Invoke(new object[] { });

            MyHelper.Copy<T>(result, data);

            return result;
        }

        public static bool Copy<T>(T result, T data)
        {
            try
            {
                if (result == null || data == null) return false;
                var list = result.GetType().GetProperties();
                foreach (var prop in list)
                {
                    var temp = prop.GetValue(data, null);
                    prop.SetValue(result, temp, null);
                }
                return true;
            }
            catch (Exception ex)
            {
                return false;
            }
        }

        public static string SearchQuery_Where<T>(T data, params string[] likeDesc)
        {
            try
            {
                string where = "";
                var properties = data.GetType().GetProperties();
                bool firstProp = false;
                for (int i = 0; i < properties.Length; ++i)
                {
                    var prop = properties[i];
                    if (prop.GetValue(data, null) == null) continue;

                    string value = prop.GetValue(data, null).ToString();
                    if (value == "") continue;

                    foreach (string desc in likeDesc)
                    {
                        int start = desc.IndexOf(prop.Name);
                        if (start == -1) continue;

                        bool ok = true;
                        for (int j = 0; j < desc.Length; ++j)
                            if ((j < start || j >= start + prop.Name.Length) && desc[j] != '%' && desc[j] != '\'')
                            {
                                ok = false;
                                break;
                            }

                        if (!ok) continue;

                        if (firstProp == false) firstProp = true; else where += " and ";
                        where += " " + prop.Name;
                        where += " like ";
                        string p = desc.Replace(prop.Name, value);
                        where += p;
                        break;
                    }
                }
                return where;
            }
            catch (Exception ex)
            {
                return ex.ToString();
            }
        }

        public static int GetDayOfYear(int year)
        {
            return (new DateTime(year + 1, 1, 1) - new DateTime(year, 1, 1)).Days;
        }

        public static int GetDayOfMonth(int year, int month)
        {
            DateTime dt1 = new DateTime(year, month, 1);
            DateTime dt2 = dt1.AddMonths(1);
            return (dt2 - dt1).Days;
        }

    }

    //Function class
    public static class ActionMenuButton
    {
        public static mvvmActionMenuViewModel actionControl;
        public const string Update = "Update";
        public const string Delete = "Delete";
        public const string Insert = "Insert";
        public const string Search = "Search";
        public const string Edit = "Edit";
        public const string View = "View";
        public const string Approve = "Approve";
        public const string Close = "Close";
    }

    public class FocusTextBox : ICommand
    {
        public bool CanExecute(object parameter)
        {
            return true;
        }

        public event EventHandler CanExecuteChanged;

        public void Execute(object parameter)
        {
            (parameter as TextBox).Text = MyHelper.CoverBackMoney((parameter as TextBox).Text);
            (parameter as TextBox).SelectionLength = 0;
            (parameter as TextBox).SelectionStart = (parameter as TextBox).Text.Length;
        }
    }

    public class ItemYesNo
    {
        public string Id { get; set; }
        public string Name { get; set; }
    }

    public class ParentMessage : MessageBase
    {
        public object currentObject { get; set; }
        public bool isEdit { get; set; }
        public string level { get; set; }
        public int index { get; set; }
        public string action { get; set; }
    }

    public class ChildMessage : MessageBase
    {
        public object currentObject { get; set; }
        public bool isEdit { get; set; }
        public string level { get; set; }
        public int index { get; set; }
        public string action { get; set; }
    }

    public class Message1 : MessageBase
    {
        public string level { get; set; }
        public int index { get; set; }
    }
    public class MessageRate : MessageBase
    {
        public string type { get; set; }
        public string actype { get; set; }
    }

    public static class MyHelperFunction
    {
        public static int GetDayOfYear(int year)
        {
            return (new DateTime(year + 1, 1, 1) - new DateTime(year, 1, 1)).Days;
        }
    }

    public static class CurrentSystemInfor
    {       
        public static DateTime CurrentDate { get; set; }        
        public static string CurrentMenuId { get; set; }        
        public static Frame CurrentFrame { get; set; }
        public static Dictionary<string, string> AvailableLink { get; set; }
        public static ObservableCollection<int> lstOption { get; set; }
    }

    public class ChangeText : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            if (value == null) return 0;
            return MyHelper.Format_Price(value.ToString());
        }

        public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            throw new NotImplementedException();
        }

        public string Format_Price(string Price)
        {
            return MyHelper.Format_Price(Price);
        }

    }

    public class ChangeDate : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            if (value == null)
                return "";
            else
                return FormatDateOnly(value.ToString());
            //return FormatDateOnly(value.ToString());
        }

        private string FormatDateOnly(string value)
        {
            return value.Split(' ')[0];
        }

        public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }

    public class ChangeLongDate : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            if (value == null)
                return "";
            else
            {
                DateTime temp = DateTime.Parse(value.ToString());
                return temp.ToShortDateString() + " " + temp.ToShortTimeString();
            }
            //return FormatDateOnly(value.ToString());
        }        

        public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }
    
    public static class GetFirtDate
    {
        //Return kieu MM-dd-yyyy
        public static string GetFirtdateOfMonth(DateTime CurrentDate)
        {
            return CurrentDate.Month + "/" + "1" + "/" + CurrentDate.Year;
        }
        public static string GetFirtDateOfQuarter(DateTime CurrentDate)
        {
            switch (CurrentDate.Month)
            {
                case 1:
                case 2:
                case 3:
                    return "1/1/" + CurrentDate.Year;
                case 4:
                case 5:
                case 6:
                    return "4/1/" + CurrentDate.Year;
                case 7:
                case 8:
                case 9:
                    return "7/1/" + CurrentDate.Year;
                case 10:
                case 11:
                case 12:
                    return "10/1/" + CurrentDate.Year;
                default: return "";
            }
        }
        public static string GetFirtdateOfYear(DateTime CurrentDate)
        {
            return "1/1/" + CurrentDate.Year;
        }
    }

    public static class ValidateTest
    {
        public static bool IsNumber(string number)
        {
            return Regex.IsMatch(number, "^[0-9]{0,20}$");
        }

        public static bool IsDecimalNumber(string number)
        {
            return Regex.IsMatch(number, "^[0-9,.,(,)]{0,20}$");
        }

        public static bool IsPhoneNumber(string number)
        {
            return Regex.IsMatch(number, "^[0-9,+,(,), ]{0,20}$");
        }

        public static bool IsEmail(string email)
        {
            return Regex.IsMatch(email, "^([0-9a-zA-Z]([-\\.\\w]*[0-9a-zA-Z])*@([0-9a-zA-Z][-\\w]*[0-9a-zA-Z]\\.)+[a-zA-Z]{2,9})$");
        }
    }
}
